package com.cls.common.message;

import com.cls.common.message.receive.IRedisMessageReceive;
import com.cls.common.message.receive.impl.ClientMessageReceiveImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

import java.util.Map;

@Configuration
public class RedisChannelConfig {

    @Value("${spring.redis.database}")
    private String redisDatabaseIndex;

    /**
     * redis消息监听器容器
     * 可以添加多个监听不同话题的redis监听器，只需要把消息监听器和相应的消息订阅处理器绑定，该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     *
     * @param connectionFactory
     * @param listenerAdapter
     * @return
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            Map<String, MessageListenerAdapter> listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //订阅主题
        listenerAdapter.forEach((clazzName, clazz) -> {
            //clazzName中加入redis数据库的下标防止消息重复消费
            container.addMessageListener(clazz, new ChannelTopic(redisDatabaseIndex + clazzName));
        });
        return container;
    }

    /**
     * 客户端消息处理
     *
     * @return
     * @author Carey
     * @date: 2020/5/27 11:52 上午
     */
    @ConditionalOnProperty(prefix = "redisReceive", name = "baseMessage", havingValue = "true")
    @Bean(name = RedisReceiveType.CLIENT_MESSAGE)
    MessageListenerAdapter clientMessageListenerAdapter(ClientMessageReceiveImpl receive) {
        return new MessageListenerAdapter(receive, IRedisMessageReceive.RECEIVE_METHOD_NAME);
    }
}